package org.bt.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;
import org.bt.common.constant.CommonConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * JWT工具类
 *
 * @author tongw
 * @date 2021/8/10
 */
@Component
public class JwtTokenUtil {

	/**
	 * Token过期时间30分钟（用户登录过期时间是此时间的两倍，以token在reids缓存时间为准）
	 */
	public static final long EXPIRE_TIME = 30 * 60 * 1000;
	private final static String CLAIM_KEY = "username";

	@Autowired
	private RedisUtil redisUtil;

	/**
	 * 生成签名,5min后过期
	 *
	 * @param username 用户名
	 * @param password   用户的密码
	 * @return 加密的token
	 */
	public String sign(String username, String password) {
		Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
		Algorithm algorithm = Algorithm.HMAC256(password);
		// 附带username信息
		return JWT.create().withClaim(CLAIM_KEY, username).withExpiresAt(date).sign(algorithm);
	}

	/**
	 * 校验token是否合法或过期
	 *
	 * @param token  密钥
	 * @param password 用户的密码
	 * @return 是否正确
	 */
	public boolean verify(String token, String username, String password) {
		try {
			// 根据密码生成JWT效验器
			Algorithm algorithm = Algorithm.HMAC256(password);
			JWTVerifier verifier = JWT.require(algorithm).withClaim(CLAIM_KEY, username).build();
			// 效验TOKEN
			return verifier.verify(token).getToken().equals(token);
		} catch (Exception exception) {
			return false;
		}
	}

	/**
	 * 获得token中的信息无需secret解密也能获得
	 *
	 * @return token中包含的用户名
	 */
	public String getUsername(String token) {
		try {
			DecodedJWT jwt = JWT.decode(token);
			return jwt.getClaim(CLAIM_KEY).asString();
		} catch (JWTDecodeException e) {
			return null;
		}
	}

//	/**
//	 * 获取 request 里传递的 token
//	 *
//	 * @param request
//	 * @return
//	 */
//	public String getToken(HttpServletRequest request) {
//		String token = request.getParameter(CommonConstant.Token.TOKEN_PARAM_KEY);
//		if (token == null) {
//			token = request.getHeader(CommonConstant.Token.TOKEN_HEADER_KEY);
//		}
//		return token;
//	}

	/**
	 * 刷新token（保证用户在线操作不掉线）
	 * @param token
	 * @param userName
	 * @param passWord
	 * @return
	 */
	private boolean tokenRefresh(String token, String userName, String passWord) {
		String cacheToken = String.valueOf(redisUtil.get(CommonConstant.Token.PREFIX_USER_TOKEN + token));
		if (StringUtils.isNotEmpty(cacheToken)) {
			// 校验token有效性
			if (!verify(cacheToken, userName, passWord)) {
				String newAuth = sign(userName, passWord);
				// 设置Toekn缓存有效时间
				redisUtil.set(CommonConstant.Token.PREFIX_USER_TOKEN + userName, newAuth);
				redisUtil.expire(CommonConstant.Token.PREFIX_USER_TOKEN + token, EXPIRE_TIME*2 / 1000);
			}

			return true;
		}
		return false;
	}

}
